package com.mpgame.common.network;

import com.mpgame.common.utils.Log;
import com.mpgame.common.constants.Constants.CGrpc;

import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.BindableService;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class GrpcServer {
    private final int port;
    private Server server;
    private final ServerBuilder<?> builder;

    public GrpcServer(int port){
        this.port = port;
        this.builder = configBuilder();
    }
    private ServerBuilder<?> configBuilder(){
        return ServerBuilder.forPort(port)
                .keepAliveTime(CGrpc.KEEP_ALIVE_TIME_SEC, CGrpc.TIME_UNIT)
                .keepAliveTimeout(CGrpc.KEEP_ALIVE_TIMEOUT_SEC, CGrpc.TIME_UNIT)
                .permitKeepAliveTime(CGrpc.KEEP_ALIVE_TIME_SEC, CGrpc.TIME_UNIT)
                .permitKeepAliveWithoutCalls(CGrpc.KEEP_ALIVE_WITHOUT_CALLS)
                .maxInboundMessageSize(CGrpc.MAX_INBOUND_MSG_BYTES)
                .maxInboundMetadataSize(CGrpc.MAX_INBOUND_METADATA_BYTES);
    }

    public void start() throws IOException {
        this.server = builder.build().start();
        Log.info("gRPC服务器启动成功，端口号：" + port);

        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            Log.info("正在关闭gRPC服务器...");
            try{
                GrpcServer.this.stop();
            }
            catch(InterruptedException e){
                Log.err("gRPC服务器关闭失败：" + e.getMessage());
            }
        }));
    }
    public GrpcServer registService(BindableService svc){
        this.builder.addService(svc);
        return this;
    }

    public void stop() throws InterruptedException{
        if(server != null){
            server.shutdown().awaitTermination(30, TimeUnit.SECONDS);
        }
    }

    public void blockUntilShutdown() throws InterruptedException{
        if(server != null){
            server.awaitTermination();
        }
    }
}
